package com.dai.rpc.server;

import com.dai.rpc.annotation.MyService;
import com.dai.rpc.config.MyRpcConfig;
import com.dai.rpc.constant.MyRpcConstants;
import com.dai.rpc.exceptions.MyRpcException;
import com.dai.rpc.factory.SingletonFactory;
import com.dai.rpc.netty.NettyServer;
import com.dai.rpc.register.zookeeper.ZKServiceRegistry;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 服务发布与获取
 */
@Slf4j
public class MyServiceProvider {

    private final Map<String, Object> serviceMap;
    private final ZKServiceRegistry zkServiceRegistry;
    private MyRpcConfig myRpcConfig;

    public MyServiceProvider(){
        //发布的服务 都在这里
        serviceMap = new ConcurrentHashMap<>();
        zkServiceRegistry = SingletonFactory.getInstance(ZKServiceRegistry.class);
    }

    public void publihService(MyService myService, Object bean) {
        registService(myService, bean);
        // 启动NettyServer,发布服务
        // 保证单例
        NettyServer nettyServer = SingletonFactory.getInstance(NettyServer.class);
        nettyServer.setMyServiceProvider(this);
        if(!nettyServer.isRunning()){
            nettyServer.run();
        }
    }

    private void registService(MyService myService, Object bean) {

        String version = myService.version();
        String serviceName = bean.getClass().getInterfaces()[0].getCanonicalName();
        log.info("发布了服务：{}",serviceName + version);
        serviceMap.put(serviceName + version, bean);

        // 同步注册到zookeeper中
        if(myRpcConfig == null){
            throw new MyRpcException("必须开启EnableRpcClient");
        }
        String serverName = myRpcConfig.getZKGroup() + serviceName + version;
        try {
            InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getLocalHost().getHostAddress(),myRpcConfig.getProviderPort());
            zkServiceRegistry.registerService(serverName,socketAddress);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

    }

    public Object getService(String serviceName){
        // 加上组名
        //serviceName = MyRpcConstants.RPC_ZK_GROUP + serviceName;
        return serviceMap.get(serviceName);
    }

    public void init(MyRpcConfig myRpcConfig){
        this.myRpcConfig = myRpcConfig;
    }
}
